package com.dream.technology.service.impl;

import com.dream.technology.components.riskControl.SymbolAnalysis;
import com.dream.technology.components.riskControl.tianji.RcConstan;
import com.dream.technology.db.dao.RcFlowMapper;
import com.dream.technology.db.dao.RcRuleCollectionMapper;
import com.dream.technology.db.dao.RcRuleMapper;
import com.dream.technology.db.entity.*;
import com.dream.technology.db.entity.vo.VoRule;
import com.dream.technology.service.RcFlowItemService;
import com.dream.technology.service.RcRuleCollectionService;
import com.dream.technology.service.RcRuleItemService;
import com.dream.technology.service.RcRuleService;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service("rcRuleService")
public class RcRuleServiceImpl implements RcRuleService {

    private static final Logger logger = LoggerFactory.getLogger(RcRuleCollectionService.class);
    @Autowired
    RcRuleMapper rcRuleMapper;
    @Autowired
    SymbolAnalysis symbolAnalysis;
    /*@Autowired
    private AdminClient adminClient;*/
    @Autowired
    RcRuleItemService rcRuleItemService;
    @Autowired
    RcFlowMapper flowMapper;
    @Autowired
    RcRuleCollectionMapper rcRuleCollectionMapper;
    @Autowired
    private RcFlowItemService rcFlowItemService;

    @Override
    public int countByExample(RcRuleQuery example) {
        return rcRuleMapper.countByExample(example);
    }

    @Override
    @Transactional
    public int deleteByExample(RcRuleQuery example) {
        return rcRuleMapper.deleteByExample(example);
    }

    @Override
    @Transactional
    public int deleteByPrimaryKey(Long id) {
        return rcRuleMapper.deleteByPrimaryKey(id);
    }

    @Override
    @Transactional
    public int insert(RcRule record) {
        return rcRuleMapper.insert(record);
    }

    @Override
    @Transactional
    public String insertStr(VoRule rcRule) {
        logger.debug("addCustomerTagSetting str ========{}", rcRule);
        //获取管理员id
        /*GenericRspDTO<OperationAdmin> userInfo = adminClient.getUserInfoByToken();
        Integer id = userInfo.getBody().getId();
        String creator = userInfo.getBody().getUserName();
        String riskControlClaCode = RandomCode.getRiskControlClaCode();
*/
        RcRule rule = rcRule.getRcRule();
        List<RcRuleItem> rcRuleItems = rcRule.getRcRuleItem();
      /*  rule.setAdminId(Long.valueOf(id));
        rule.setCreator(creator);
        String desc = checkRule(rcRule);
        rule.setRuleDesc(desc);
        rule.setRuleCode(riskControlClaCode);*/
        rule.setStatus(false);
        insert(rule);
        ArrayList<RcRuleItem> tagItems = new ArrayList<>();
        for (int i = 0; i < rcRuleItems.size(); i++) {
            RcRuleItem rcRuleItem = rcRuleItems.get(i);
            rcRuleItem.setRuleId(rule.getId());
            // 解析民族：["汉","回","藏","苗"] 变成 汉,回,藏,苗
            if ("nation".equals(rcRuleItem.getFieldCode())) {
            	rcRuleItem.setFieldValue(rcRuleItem.getFieldValue().replaceAll("\"|\\[|\\]", ""));
            } else {
            	if (rcRuleItem.getFieldValue().contains(",")) {
                	String[] sys = rcRuleItem.getSymbolCode().split(",");
            		String[] split = rcRuleItem.getFieldValue().split(",");
            		if (sys.length < 2) {
            			rcRuleItem.setFieldValue(split[0]);
            			rcRuleItem.setSymbolCode(sys[0]);
            		} else {
            			if ("undefined".equals(sys[1])) {
            				rcRuleItem.setFieldValue(split[0]);
                			rcRuleItem.setSymbolCode(sys[0]);
            			}
            		}
                }
            }
            tagItems.add(rcRuleItem);
        }
        rcRuleItemService.insertList(tagItems);
        return "success";
    }

    @Override
    @Transactional
    public int insertSelective(RcRule record) {
        return rcRuleMapper.insertSelective(record);
    }

    @Override
    public List<RcRule> selectByExample(RcRuleQuery example) {
        return rcRuleMapper.selectByExample(example);
    }

    @Override
    public RcRule selectByPrimaryKey(Long id) {
        return rcRuleMapper.selectByPrimaryKey(id);
    }

    @Override
    @Transactional
    public int updateByExampleSelective(RcRule record, RcRuleQuery example) {
        return rcRuleMapper.updateByExampleSelective(record, example);
    }

    @Override
    @Transactional
    public int updateByExample(RcRule record, RcRuleQuery example) {
        return rcRuleMapper.updateByExample(record, example);
    }

    @Override
    @Transactional
    public int updateByPrimaryKeySelective(RcRule record) {
        return rcRuleMapper.updateByPrimaryKeySelective(record);
    }

    @Override
    @Transactional
    public int updateByPrimaryKey(RcRule record) {
        return rcRuleMapper.updateByPrimaryKey(record);
    }

    /**
     * 查询指定id的规则集合
     * 配置规则集验证
     *
     * @param ids
     * @return
     */
    @Override
    public List<RcRule> selectByIdInList(List<Long> ids) {
        return rcRuleMapper.selectByIdInList(ids);
    }

    /**
     * 解析规则 返回文本
     *
     * @param rule
     * @return
     */
    @Override
    public String checkRule(VoRule rcRule) {
        logger.debug("checkuleRSetting str ========{}", rcRule);
        RcRule rule = rcRule.getRcRule();
        List<RcRuleItem> rcRuleItems = rcRule.getRcRuleItem();
        String action = null;
        Map<String, String> itemsMap = new HashMap<>(rcRuleItems.size() << 1);
        for (int i = 0; i < rcRuleItems.size(); i++) {
            // 重新映射 别名与描述
            RcRuleItem rcRuleItem = rcRuleItems.get(i);
            String symbolCode = rcRuleItem.getSymbolCode();
            String itemAlias = rcRuleItem.getItemAlias();
            String fieldName = rcRuleItem.getFieldName();
            // 解析民族：["汉","回","藏","苗"] 变成 汉,回,藏,苗
            String fieldValue = null;
            if ("nation".equals(rcRuleItem.getFieldCode())) {
            	fieldValue = rcRuleItem.getFieldValue().replaceAll("\"|\\[|\\]", "");
            } else {
            	fieldValue = rcRuleItem.getFieldValue();
            }
            //状态
            action = rcRuleItem.getRuleAction() == 0 ?" 拒绝":" 通过";
            String s = symbolAnalysis.analysisSymbolName(fieldName, symbolCode, fieldValue);
            itemsMap.put(itemAlias, s);
        }
        return symbolAnalysis.getExp(rule.getRule(), itemsMap) + action;
    }


    /**
     * 修改规则前检查rule引用 返回应用的规则集 规则流程
     *
     * @param id
     * @return
     */
    @Override
    public Map<String, Object> checkRuleRef(Long id) {
        logger.debug("checkuleRefSetting str ========{}", id);
        Map<String, Object> map = new HashMap<String, Object>();
        List<RcRuleCollection> rcRuleCollections = rcRuleCollectionMapper.selectRcRuleCollectionById(id);
        List<RcFlow> rcFlows = flowMapper.queryFlowByTag(1, id);
        map.put("ruleCollectionCount", rcRuleCollections.size());
        map.put("flowCount", rcFlows.size());
        return map;
    }

    /**
     * 复制规则
     *
     * @param id
     * @param name
     * @param code
     * @return
     */
    @Override
    @Transactional
    public String copy(Long id, String ruleName, String ruleDetail, Boolean enabled) {
        RcRule rcRule = rcRuleMapper.selectByPrimaryKey(id);
//        rcRule.setRuleCode(RandomCode.getRiskControlClaCode());
        rcRule.setId(null);
        rcRule.setRuleName(ruleName);
        rcRule.setRuleDetail(ruleDetail);
        rcRule.setEnabled(enabled);
        rcRule.setCreateDate(new Date());
        insertSelective(rcRule);
        rcRuleItemService.copy(id, rcRule.getId());
        return RcConstan.SUCCESS;
    }

    /**
     * 解析自定义json 修改规则
     *
     * @param
     * @return
     */
    @Override
    public String updateByJsonStr(VoRule voRule) {
        logger.debug("updateByJsonStr str ========{}", voRule);
        // 前端传回来的规则
        RcRule rcRule = voRule.getRcRule();
        // 原规则
        RcRule rcRuleOld = rcRuleMapper.selectByPrimaryKey(rcRule.getId());
        List<RcRuleItem> rcRuleItems = voRule.getRcRuleItem();
        String desc = checkRule(voRule);
        rcRule.setRuleDesc(desc);
        updateByPrimaryKeySelective(rcRule);
        List<RcRuleItem> oldItems = rcRuleItemService.selectByRuleId(rcRule.getId());
        ArrayList<Long> itemIds = new ArrayList<>();
        rcRuleItems.forEach(item -> {
            if (item.getId() != null) {
            	// 解析民族：["汉","回","藏","苗"] 变成 汉,回,藏,苗
	            String fieldValue = null;
	            if ("nation".equals(item.getFieldCode())) {
	            	fieldValue = item.getFieldValue().replaceAll("\"|\\[|\\]", "");
	            } else {
	            	fieldValue = item.getFieldValue();
	            }
	            item.setFieldValue(fieldValue);
                //修改
              rcRuleItemService.updateByPrimaryKeySelective(item);
              itemIds.add(item.getId());
            } else {
//                添加
                item.setRuleId(rcRule.getId());
                item.setStatus(false);
                rcRuleItemService.insertSelective(item);
            }
        });
        //删除
        List<RcRuleItem> deleteItem = oldItems.stream().filter(item -> !itemIds.contains(item.getId())).collect(Collectors.toList());
        deleteItem.forEach(del ->rcRuleItemService.deleteByPrimaryKey(del.getId()));
        // 修改规则名称，需要同步子流程中引用的此规则的名称
 		if (!rcRuleOld.getRuleName().equals(rcRule.getRuleName())) {
 			// 查询引用此规则的子流程
 			RcFlowItemQuery flowItemQuery = new RcFlowItemQuery();
 			RcFlowItemQuery.Criteria criteria = flowItemQuery.createCriteria();
 			criteria.andChildItemIdEqualTo(rcRuleOld.getId());
 			criteria.andChildItemTypeEqualTo(1);
 			List<RcFlowItem> flowItemList = rcFlowItemService.selectByExample(flowItemQuery);
 			if (CollectionUtils.isNotEmpty(flowItemList)) {
 				for (RcFlowItem item : flowItemList) {
 					RcFlowItem itemNew = new RcFlowItem();
 					itemNew.setId(item.getId());
 					itemNew.setChildItemName(rcRule.getRuleName());
 					rcFlowItemService.updateByPrimaryKeySelective(itemNew);
 				}
 			}
 		}
        return null;
    }
}
